package ee.subjects.backend.services;

import java.sql.Connection;
import java.sql.SQLException;

import org.apache.log4j.Logger;

import ee.subjects.backend.database.ConnectionManager;
import ee.subjects.backend.model.dao.EmployeeDAO;
import ee.subjects.backend.model.dao.User_account_DAO;
import ee.subjects.backend.model.dao.factory.DAOFactory;
import ee.subjects.backend.model.data.Employee;
import ee.subjects.backend.model.data.User_account;
import ee.subjects.backend.model.data.subjectdbtypetablesconstants.SubjectDBTypeTablesConstants;

public class UserAccountAndAuthenticationServiceImpl implements UserAccountAndAuthenticationService
{
	Logger logger = Logger.getLogger(UserAccountAndAuthenticationServiceImpl.class);
	DAOFactory daoFactory = DAOFactory.getDAOFactory(); //PEAB ILMTINGIMATA ENNE ConnectionManageri olema SEST INITSIALISEERIB PROPERTIES ANDMED ConnectionManageri jaoks
	public final int EMPLOYEE_SUBJECT_TYPE_IDENTIFICATOR = 3;
	public final int STATUS_OF_A_USER_ACCOUNT = 1;
	public final String PASSWORD_WILL_NOT_EXPIRE = "Y";
	
	@Override
	public int createNewEmployeeTypeUser(int employeeId, String username, String password) 
	{
		int CREATION_SUCCESSFUL = 1;
		int CREATION_UNSUCCESSFUL_DUE_TO_THAT_THERE_IS_NO_SUCH_EMPLOYEE = -2;
		int CREATION_UNSUCCESSFUL = -1;
		Connection dbConnection = ConnectionManager.getInstance().getConnection();
		setAutoCommitToFalse(dbConnection);
		EmployeeDAO employeeDAOImpl = daoFactory.getEmployeeDAOImpl(dbConnection);
		User_account_DAO user_account_DAOImpl = daoFactory.getUser_account_DAOImpl(dbConnection);
		
		try 
		{
			//Kontrollin esmalt, kas antud employeeId on ikka Employee tabelis olemas, et huupi id-d ei 
			//sisestataks
			Employee employeeToCheck = employeeDAOImpl.getEmployeeById(employeeId);
			if (employeeToCheck == null)
			{
				return CREATION_UNSUCCESSFUL_DUE_TO_THAT_THERE_IS_NO_SUCH_EMPLOYEE;
			}
			
			User_account user_account = new User_account();
			user_account.setSubject_fk(employeeId);
			user_account.setSubject_type_fk(EMPLOYEE_SUBJECT_TYPE_IDENTIFICATOR);
			user_account.setUsername(username);
			user_account.setPassw(password);
			user_account.setStatus(STATUS_OF_A_USER_ACCOUNT);
			user_account.setPassword_never_expires(PASSWORD_WILL_NOT_EXPIRE);
			
			int wasInsertionSuccessful = user_account_DAOImpl.insertUser_account(user_account);
			
			dbConnection.commit();
			
			if (wasInsertionSuccessful == CREATION_SUCCESSFUL)
			{
				return CREATION_SUCCESSFUL;
			}
			else
			{
				return CREATION_UNSUCCESSFUL;
			}
		} 
		catch (Exception e) 
		{
			rollBackATransaction(dbConnection);
			e.printStackTrace();
			return CREATION_UNSUCCESSFUL;
		}
		finally
		{
			ConnectionManager.getInstance().closeConnection();
		}		
	}
	
	@Override
	public Employee getAuthenticatedEmployee(String username, String password) 
	{
		Connection dbConnection = ConnectionManager.getInstance().getConnection();
		User_account_DAO user_account_DAOImpl = daoFactory.getUser_account_DAOImpl(dbConnection);
		User_account user_accountAuthenticated = null;
		EmployeeDAO employeeDAOImpl = daoFactory.getEmployeeDAOImpl(dbConnection);
		Employee employeeAuthenticated = null;
		
		try 
		{
			user_accountAuthenticated = user_account_DAOImpl.getAuthenticatedUser_account(username, password);
			if ((user_accountAuthenticated != null) &&
					(user_accountAuthenticated.getSubject_type_fk() == SubjectDBTypeTablesConstants.EMPLOYEE_SUBJECT_TYPE_IDENTIFICATOR))
			{
				employeeAuthenticated = employeeDAOImpl.getEmployeeById(user_accountAuthenticated.getSubject_fk());
			}
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		finally
		{
			ConnectionManager.getInstance().closeConnection();
		}
		
		return employeeAuthenticated;
	}

	@Override
	public int updateUsername(int employeeId, String oldUsername, String password,
			String newUsername) 
	{
		int UPDATE_SUCCESSFUL = 1;
		int UPDATE_UNSUCCESSFUL_DUE_TO_THAT_THERE_IS_NO_SUCH_EMPLOYEE = -2;
		int UPDATE_UNSUCCESSFUL = -1;
		boolean doesEmployeeExistsInUserAccounts = false;
		boolean wasUpdateSuccessful = false;
		Connection dbConnection = ConnectionManager.getInstance().getConnection();
		setAutoCommitToFalse(dbConnection);
		User_account_DAO user_account_DAOImpl = daoFactory.getUser_account_DAOImpl(dbConnection);
		
		try 
		{
			//Esmalt kontrollin, kas antud employeeId on user_account tabelis olemas
			doesEmployeeExistsInUserAccounts = user_account_DAOImpl.isThereAnEmployeeIdInUserAccounts(employeeId);
			if (!doesEmployeeExistsInUserAccounts)
			{
				return UPDATE_UNSUCCESSFUL_DUE_TO_THAT_THERE_IS_NO_SUCH_EMPLOYEE;
			}
			
			wasUpdateSuccessful = user_account_DAOImpl.updateEmployeeUsername(employeeId, oldUsername, password, newUsername);
			
			dbConnection.commit();
			
			if (wasUpdateSuccessful == true)
			{
				return UPDATE_SUCCESSFUL;
			}
			else
			{
				return UPDATE_UNSUCCESSFUL;
			}
		} 
		catch (Exception e) 
		{
			rollBackATransaction(dbConnection);
			e.printStackTrace();
			return UPDATE_UNSUCCESSFUL;
		}
		finally
		{
			ConnectionManager.getInstance().closeConnection();
		}		
	}


	@Override
	public int updatePassword(int employeeId, String username, String oldPassword,
			String newPassword) 
	{
		int UPDATE_SUCCESSFUL = 1;
		int UPDATE_UNSUCCESSFUL_DUE_TO_THAT_THERE_IS_NO_SUCH_EMPLOYEE = -2;
		int UPDATE_UNSUCCESSFUL = -1;
		boolean doesEmployeeExistsInUserAccounts = false;
		boolean wasUpdateSuccessful = false;
		Connection dbConnection = ConnectionManager.getInstance().getConnection();
		setAutoCommitToFalse(dbConnection);
		User_account_DAO user_account_DAOImpl = daoFactory.getUser_account_DAOImpl(dbConnection);
		
		try 
		{
			//Esmalt kontrollin, kas antud employeeId on user_account tabelis olemas
			doesEmployeeExistsInUserAccounts = user_account_DAOImpl.isThereAnEmployeeIdInUserAccounts(employeeId);
			if (!doesEmployeeExistsInUserAccounts)
			{
				return UPDATE_UNSUCCESSFUL_DUE_TO_THAT_THERE_IS_NO_SUCH_EMPLOYEE;
			}
			
			wasUpdateSuccessful = user_account_DAOImpl.updateEmployeePassword(employeeId, username, oldPassword, newPassword);
			
			dbConnection.commit();
			
			if (wasUpdateSuccessful == true)
			{
				return UPDATE_SUCCESSFUL;
			}
			else
			{
				return UPDATE_UNSUCCESSFUL;
			}
		} 
		catch (Exception e) 
		{
			rollBackATransaction(dbConnection);
			e.printStackTrace();
			return UPDATE_UNSUCCESSFUL;
		}
		finally
		{
			ConnectionManager.getInstance().closeConnection();
		}		
	}
	
	//----------HELPER METHODS-----------------
	private void setAutoCommitToFalse(Connection databaseConnection)
	{
		try 
		{
			databaseConnection.setAutoCommit(false);
			logger.info("Autocommit is now set to false");
		} 
		catch (SQLException e) 
		{
			logger.error(e.getMessage());
		}
	}
	
	private void rollBackATransaction(Connection databaseConnection)
	{
		try 
		{
			databaseConnection.rollback();
			logger.info("Rollback has been done!");
		} 
		catch (SQLException e) 
		{
			e.printStackTrace();
		}
	}
}
